package com.liusu.spider.request;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.junit.jupiter.api.Test;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.*;


public class Request {

    public static PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager();


    /**
     * 发送GET请求,获取HTML代码
     * @param url 请求路径
     * @param param 请求参数
     * @param headers 请求头
     * @return
     */
    public String get(String url, Map<String,Object> param, HashMap<String,String> headers, String charset) {
        /**
         * 获取客户端对象
         */
        CloseableHttpClient client = HttpClients.custom().setConnectionManager(manager).build();
        URI uri = null;
        String html = "";
        CloseableHttpResponse response = null;
        try {
            /**
             * 构建请求参数
             */
            URIBuilder builder = new URIBuilder(url);

            if(param != null){
                for(String k: param.keySet()){
                    builder.addParameter(k,param.get(k).toString());
                }
            }

            uri = builder.build();
            HttpGet get = new HttpGet(uri);
            if(headers != null){
                for(String k: headers.keySet()){
                    get.setHeader(k,headers.get(k));
                }
            }
            /**
             * 设置请求头
             */
            get.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3870.400 QQBrowser/10.8.4405.400");
            /**
             * 向服务器发送请求
             */
            response = client.execute(get);

            html = EntityUtils.toString(response.getEntity(),charset);


        } catch (URISyntaxException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(response!=null){
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return html;
    }
    /**
     * 发送GET请求,获取HTML代码
     * @param url
     *
     */
    public String get(String url) {
        return this.get(url,null,null,"utf-8");
    }
    /**
     * 发送GET请求,获取HTML代码
     * @param url
     *
     */
    public String get(String url,String charset) {
        return this.get(url,null,null,charset);
    }
    /**
     * 发送GET请求,获取HTML代码
     * @param url
     *
     */
    public String get(String url,Map<String,Object> param) {
        return this.get(url,param,null,"utf-8");
    }
    /**
     * 发送GET请求,获取HTML代码
     * @param url
     *
     */
    public String get(String url,Map<String,Object> param,String charset) {
        return this.get(url,param,null,charset);
    }
    /**
     * 发送GET请求,获取HTML代码
     * @param url
     * @param param
     *
     */
    public String get(String url, HashMap<String,String> headers) {
        return get(url,null,headers,"utf-8");
    }
    /**
     * 发送GET请求,获取HTML代码
     * @param url
     * @param param
     *
     */
    public String get(String url, HashMap<String,String> headers,String charset) {
        return get(url,null,headers,charset);
    }
    /**
     * 发送GET请求,获取HTML代码
     * @param url
     * @param param
     *
     */
    public String get(String url,Map<String,Object> param, HashMap<String,String> headers) {
        return get(url,param,headers,"utf-8");
    }

    /**
     * 下载文件
     * @param url 文件的下载地址
     * @param file 文件保存路径
     *
     */
    public Boolean download(String url, File file) {
        if(file.exists()){
            file.delete();
        }
        /**
         * 获取客户端对象
         */
        CloseableHttpClient client = HttpClients.custom().setConnectionManager(manager).build();

        Boolean success = false;
        CloseableHttpResponse response = null;
        try {
            HttpGet get = new HttpGet(url);
            /**
             * 向服务器发送请求
             */
            response = client.execute(get);

            HttpEntity entity = response.getEntity();
            if(entity != null){
                FileOutputStream stream = new FileOutputStream(file);
                entity.writeTo(stream);
                stream.close();
            }

            success = true;
        }catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(response!=null){
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return success;
    }
    public Boolean download(String url, String path) {
        File f = new File(path);
        return this.download(url,f);
    }
    /**
     * 发送POST请求,获取HTML代码
     * @param url
     * @param data
     *
     */
    public String post(String url,Map<String,Object> data,HashMap<String,String> headers,String charset){

        CloseableHttpClient client = HttpClients.custom().setConnectionManager(manager).build();

        HttpPost post = new HttpPost(url);

        List<NameValuePair> list = new ArrayList<>();

        CloseableHttpResponse response = null;
        String html = "";
        try {
            if(data != null){
                for (String k: data.keySet()) {
                    BasicNameValuePair kv = new BasicNameValuePair(k, data.get(k).toString());
                    list.add(kv);
                }
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list,"utf-8");
                post.setEntity(entity);
            }
            if(headers!=null){
                for (String k: headers.keySet()) {
                    post.setHeader(k, headers.get(k));
                }
            }
            post.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3870.400 QQBrowser/10.8.4405.400");

            response = client.execute(post);
            HttpEntity http = response.getEntity();
            html = EntityUtils.toString(http, charset);

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return html;
    }
    /**
     * 发送POST请求,获取HTML代码
     * @param url
     *
     *
     */
    public String post(String url){
        return post(url,null,null,"utf-8");
    }
    /**
     * 发送POST请求,获取HTML代码
     * @param url
     *
     *
     */
    public String post(String url,String charset){
        return post(url,null,null,charset);
    }
    /**
     * 发送POST请求,获取HTML代码
     * 只携带参数
     * @param url
     * @param data
     *
     */
    public String post(String url,Map<String,Object> data){
        return post(url,data,null,"utf-8");
    }
    /**
     * 发送POST请求,获取HTML代码
     * 只携带参数
     * @param url
     * @param data
     *
     */
    public String post(String url,Map<String,Object> data,String charset){
        return post(url,data,null,charset);
    }
    /**
     * 发送POST请求,获取HTML代码
     * 只携带参数
     * @param url
     * @param data
     *
     */
    public String post(String url,HashMap<String,String> headers){
        return post(url,null,headers,"utf-8");
    }
    /**
     * 发送POST请求,获取HTML代码
     * 只携带参数
     * @param url
     * @param data
     *
     */
    public String post(String url,Map<String,Object> data,HashMap<String,String> headers){
        return post(url,data,headers,"utf-8");
    }

}
